package com.struc.td;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Circle;
import com.badlogic.gdx.math.Intersector;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.utils.Array;

public class TowerSlow extends Tower{
	private int posX;
	private int posY;
	private boolean sold;
	private Texture entityMap;
	private Sprite tower;
	private Circle range;
	private float towerRange;
	private int upgradeSpecialCost;
	private int upgradeRangeCost;
	private float slow;
	private int towerSpecialRank;
	private int towerRangeRank;
	private int totalGoldSpent;
	private int cooldown;
	private Game game;
	private Array<Projectile> projectiles;
	private Array<Projectile> projectilesToRemove;
	private Sprite infoBackground;
	private Sprite upgradeRange;
	private Sprite upgradeSlow;
	private Sprite sellTower;
	private Sprite upgradeRangeSelect;
	private Sprite upgradeSlowSelect;
	private Sprite sellTowerSelect;
	private Sprite exitInfo; 
	private BitmapFont font;
	private Sprite towerrange;

	//our constructor will create a new slow tower on the given position
	//and initiate all the textures and values
	public TowerSlow(int x, int y, Game g){
		exitInfo = new Sprite(StaticTextures.info_panel_exitInfo,0,0,64,27);
		sellTower = new Sprite(StaticTextures.tower_slow_towerMap,0,414,87,42);
		upgradeSlow = new Sprite(StaticTextures.tower_slow_towerMap,0,240,124,42);
		upgradeRange = new Sprite(StaticTextures.tower_slow_towerMap,0,325,124,42);
		sellTowerSelect = new Sprite(StaticTextures.tower_slow_infoselected,0,414,87,42);
		upgradeSlowSelect = new Sprite(StaticTextures.tower_slow_infoselected,0,240,124,42);
		upgradeRangeSelect = new Sprite(StaticTextures.tower_slow_infoselected,0,325,124,42);
		infoBackground = new Sprite(StaticTextures.tower_slow_towerMap);
		cooldown = 0;
		posX = x;
		posY = y;
		game = g;
		projectiles = new Array<Projectile>();
		projectilesToRemove = new Array<Projectile>();
		totalGoldSpent = 100;
		towerSpecialRank = 1;
		towerRangeRank = 1;
		towerRange = 150;
		slow = 0.8f;
		upgradeSpecialCost = 8;
		upgradeRangeCost = 5;
		entityMap = StaticTextures.entity_map;
		tower = new Sprite(entityMap, 141, 64, 128, 128);
		tower.setPosition(x, y);
		range = new Circle(x+tower.getWidth()/2, y+tower.getHeight()/2, towerRange);
		tower.setSize(tower.getWidth()*0.6f,tower.getHeight()*0.6f);
		towerrange = new Sprite(StaticTextures.tower_range,30,37,196,181);
		font = StaticTextures.towerFont;
	}

	/* Calls the towers projectile's update methods.
	 * Waits for cooldown and enemies in range and
	 * createes new projectiles.
	 */
	public void update() {
		for(Projectile p : projectiles){
			p.update();
			if (p.isDead()) {
				projectilesToRemove.add(p);
			}
		}
		for (Projectile p : projectilesToRemove) {
			projectiles.removeValue(p,true);
		}
		projectilesToRemove.clear();
		cooldown-=Gdx.graphics.getDeltaTime()*1000;
		if (cooldown <= 0) {
			for(Enemy e : game.getEnemyList()){
				if(Intersector.overlapCircleRectangle(range, e.getBounds())){
					projectiles.add(new ProjectileSlow(e, posX+tower.getWidth()/2, posY+tower.getHeight()/2, slow));
					cooldown = 2000;
					break;
				}
			}
		}
	}
	//the render function for the tower and projectiles
	public void render(SpriteBatch sb) {
		tower.draw(sb);
		for(Projectile p : projectiles){
			p.render(sb);
		}
	}
	//returns a tower value
	public int towerValue(){
		return (int) (totalGoldSpent * 0.75);
	}

	//sells the tower and increases players gold
	public void sell(Player p) {
		int gold = towerValue();
		p.incGold(gold);
		sold = true;
	}

	//this method will upgrade the towers slow
	public boolean upgradeSpecial(Player p) {
		if(p.getGold() >= upgradeSpecialCost){
			p.incGold(-upgradeSpecialCost);
			totalGoldSpent += upgradeSpecialCost;
			slow -= 0.05;
			towerSpecialRank++;
			upgradeSpecialCost += 5;

			return true;
		}
		return false;

	}
	//this method will upgrade the towers range.
	public boolean upgradeRange(Player p) {
		if(p.getGold() >= upgradeRangeCost){
			p.incGold(-upgradeRangeCost);
			totalGoldSpent += upgradeRangeCost;
			towerRange += 15;
			range.radius = towerRange;
			towerRangeRank++;
			upgradeRangeCost += 5;

			return true;
		}
		return false;

	}

	public boolean getSold(){
		return sold;
	}

	public CharSequence convertToChar(int x){
		String temp = Integer.toString(x);
		return ((CharSequence) temp);
	}

	public CharSequence floatToChar(float x){
		String temp = Float.toString(x);
		return ((CharSequence) temp);
	}
	//renders a circle around our tower to show us its range
	public void renderRange(SpriteBatch sb){
		towerrange.setSize(range.radius*2, range.radius*2);
		towerrange.setPosition(posX+tower.getWidth()/2-towerrange.getWidth()/2, posY+tower.getHeight()/2-towerrange.getHeight()/2);
		towerrange.draw(sb);
	}
	//renders the infopanel of selected
	public void renderInfo(SpriteBatch sb) {
		infoBackground.setBounds(Gdx.graphics.getWidth()-Gdx.graphics.getWidth()/3, 0, Gdx.graphics.getWidth()/3, Gdx.graphics.getHeight());
		exitInfo.setBounds(infoBackground.getX(), Gdx.graphics.getHeight()-Gdx.graphics.getHeight()/15, infoBackground.getWidth()/3, infoBackground.getHeight()/15);
		sellTower.setBounds(infoBackground.getX(), 57f/512f*Gdx.graphics.getHeight(), 87f/256f*infoBackground.getWidth(), 42f/512f*Gdx.graphics.getHeight());
		upgradeRange.setBounds(infoBackground.getX(), 142f/512f*Gdx.graphics.getHeight(),124f/256f*infoBackground.getWidth() ,42f/512f*Gdx.graphics.getHeight());
		upgradeSlow.setBounds(infoBackground.getX(), 230f/512f*Gdx.graphics.getHeight(),124f/256f*infoBackground.getWidth() ,42f/512f*Gdx.graphics.getHeight());
		sellTowerSelect.setBounds(infoBackground.getX(), 57f/512f*Gdx.graphics.getHeight(), 87f/256f*infoBackground.getWidth(), 42f/512f*Gdx.graphics.getHeight());
		upgradeRangeSelect.setBounds(infoBackground.getX(), 142f/512f*Gdx.graphics.getHeight(),124f/256f*infoBackground.getWidth() ,42f/512f*Gdx.graphics.getHeight());
		upgradeSlowSelect.setBounds(infoBackground.getX(), 230f/512f*Gdx.graphics.getHeight(),124f/256f*infoBackground.getWidth() ,42f/512f*Gdx.graphics.getHeight());
		infoBackground.draw(sb,0.8f);
		upgradeRange.draw(sb);
		upgradeSlow.draw(sb);
		sellTower.draw(sb);
		exitInfo.draw(sb, 0.6f);
		font.draw(sb, floatToChar(slow), 220f/256*Gdx.graphics.getWidth(), 380f/512f*Gdx.graphics.getHeight());
		font.draw(sb, "2s", 220f/256*Gdx.graphics.getWidth(), 340f/512f*Gdx.graphics.getHeight());
		font.draw(sb, convertToChar(upgradeSpecialCost), 210f/256f*Gdx.graphics.getWidth(), 245f/512f*Gdx.graphics.getHeight());
		font.draw(sb, convertToChar(upgradeRangeCost), 210f/256f*Gdx.graphics.getWidth(), 160f/512f*Gdx.graphics.getHeight());
		font.draw(sb, convertToChar(towerValue()), 200f/256*Gdx.graphics.getWidth(), 80f/512f*Gdx.graphics.getHeight());
	}

	//renders if button has been pressed
	public void renderButtonSelect(SpriteBatch sb, ButtonSelect index){
		if(index == ButtonSelect.Special){
			upgradeSlowSelect.draw(sb);
		}
		else if(index == ButtonSelect.Range){
			upgradeRangeSelect.draw(sb);
		}
		else if(index == ButtonSelect.Sell){
			sellTowerSelect.draw(sb);
		}
	}

	public Rectangle getBounds() {
		return tower.getBoundingRectangle();
	}
	public Rectangle getInfoBounds() {
		return infoBackground.getBoundingRectangle();
	}

	public Rectangle getUpgradeRangeRect() {
		return upgradeRange.getBoundingRectangle();
	}

	public Rectangle getExitInfoRect() {
		return exitInfo.getBoundingRectangle();
	}

	public Rectangle getUpgradeSpecialRect() {
		return upgradeSlow.getBoundingRectangle();
	}
	public Rectangle getSoldRect(){
		return sellTower.getBoundingRectangle();
	}

	@Override
	public void renderCd(SpriteBatch sb) {
		// TODO Auto-generated method stub
		
	}

}
